﻿/*  Copyright © 2012 Matthew David Elgert - mdelgert@yahoo.com
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */

using System;
using System.Data;
using System.Xml;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using AlexPilotti.FTPS.Client;
using Tamir.SharpSsh.jsch;

namespace BLL
{
    /// <summary>
    /// Based on: http://ftps.codeplex.com/ & http://sharpssh2.codeplex.com/ SharpSSH2 has dependencies on http://www.mentalis.org/
    /// </summary>

    public static class ClientFTP
    {
        public static String SFTP_PWD = null;

        public static void PutFiles()
        {
            using (DataTable dt = Common.GetDBNames())
            {
                foreach (DataRow row in dt.Rows)
                {
                    PutFile(row[0].ToString());
                }
            }
        }

        public static void PutFile(string DBName)
        {

            string FileName = String.Format("{0}{1}.7z", DBName, Common.GetTimeStamp());

            XmlDocument doc = new XmlDocument();
            doc.Load("FTPServers.xml");
            XmlElement root = doc.DocumentElement;
            XmlNodeList nodes = root.SelectNodes("/XMLDocument/Server");

            foreach (XmlNode node in nodes)
            {
                string Host = null;
                int Port = 0;
                string User = null;
                string Pass = null;
                string RemoteFolder = null;
                bool SSL = false;
                bool SFTP = false;

                if (node["Host"] != null)
                {
                    Host = node["Host"].InnerText;
                }
                if (node["Port"] != null)
                {
                    Port = int.Parse(node["Port"].InnerText);
                }
                if (node["User"] != null)
                {
                    User = node["User"].InnerText;
                }
                if (node["Pass"] != null)
                {
                    Pass = node["Pass"].InnerText;
                }
                if (node["RemoteFolder"] != null)
                {
                    RemoteFolder = node["RemoteFolder"].InnerText;
                }
                if (node["SSL"] != null)
                {
                    SSL = bool.Parse(node["SSL"].InnerText);
                }
                if (node["SFTP"] != null)
                {
                    SFTP = bool.Parse(node["SFTP"].InnerText);
                }

                try
                {
                    Log.Msg(String.Format("FTP server {0} file {1} begin", Host, DBName));
                    Common.ShowProgress(true);

                    if (SFTP == false)
                    {
                        using (FTPSClient client = new FTPSClient())
                        {
                            if (SSL == true) //Use SSL
                            {
                                if (Port == 0)
                                {
                                    Port = 990;
                                }
                                client.Connect(Host, Port, new NetworkCredential(User, Pass), ESSLSupportMode.Implicit, ValidateTestServerCertificate, new X509Certificate(), 0, 0, 0, Common.GetFTPTimeOut(), true, EDataConnectionMode.Passive);
                            }
                            else // No SSL
                            {
                                if (Port == 0)
                                {
                                    Port = 21;
                                }
                                client.Connect(Host, Port, new NetworkCredential(User, Pass), ESSLSupportMode.ClearText | ESSLSupportMode.DataChannelRequested, ValidateTestServerCertificate, new X509Certificate(), 0, 0, 0, Common.GetFTPTimeOut(), true, EDataConnectionMode.Passive);
                            }
                            client.PutFile(Common.GetTempDir().Replace(@"\", @"\\") + FileName, RemoteFolder + FileName);
                            client.Close();
                        }
                    }

                    if (SFTP == true)
                    {
                        if (Port == 0)
                        {
                            Port = 22;
                        }
                        SFTP_PWD = Pass;
                        JSch jsch = new JSch();
                        Session session = jsch.getSession(User, Host, Port);
                        UserInfo ui = new MyUserInfo();
                        session.setUserInfo(ui);
                        session.connect();
                        Channel channel = session.openChannel("sftp");
                        channel.connect();
                        ChannelSftp c = (ChannelSftp)channel;
                        c.put(Common.GetTempDir().Replace(@"\", @"\\") + FileName, RemoteFolder + FileName);
                        session.disconnect();
                    }

                    Common.ShowProgress(false);
                    Log.Msg(String.Format("FTP server {0} file {1} end", Host, DBName));

                }
                catch (System.Exception ex)
                {
                    Log.Msg(String.Format("FTP server {0} file {1} failed", Host, DBName), true);
                    Log.Msg(ex.ToString(), true);
                }

            }

        }

        private static bool ValidateTestServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;    // Accept any certificate
        }

        //Sharp SSH dependency
        public class MyUserInfo : UserInfo
        {

            public String getPassword() { return SFTP_PWD; }

            public String getPassphrase() { return null; }

            public bool promptPassphrase(String message) { return true; }

            public bool promptYesNo(String str)
            {
                return true;
            }

            public bool promptPassword(String message)
            {
                return true;
            }

            public void showMessage(String message)
            {
            }

        }
    }

}
